#include <QQmlContext>
#include "QQuickROData.h"
#include "ROLoader.h"

ROLoader::ROLoader(QObject *parent):ROSyncCreation(parent)
{
}

QUrl ROLoader::source() const
{
    return m_source;
}

void ROLoader::setSource(const QUrl &newSource)
{
    if(role() == Client && m_block)
    {
        qDebug()<<__func__<<"操作失败，只有服务端可以修改该属性";
        return;
    }

    if (m_source == newSource)
        return;
    m_source = newSource;
    if(role() == Host)
    {
        validate();
    }
    emit sourceChanged();
}

QQmlComponent *ROLoader::sourceComponent() const
{
    return m_sourceComponent;
}

void ROLoader::setSourceComponent(QQmlComponent *newSourceComponent)
{
    if(role() == Client && m_block)
    {
        qDebug()<<__func__<<"操作失败，只有服务端可以修改该属性";
        return;
    }

    if (m_sourceComponent == newSourceComponent)
        return;
    m_sourceComponent = newSourceComponent;
    if(role() == Host)
    {
        validate();
    }
    emit sourceComponentChanged();
}

void ROLoader::validate()
{
    clean();

    QStringList reason;

    if(!m_source.isEmpty())
    {
        reason = {"url",m_source.toString()};
        m_realComponent = new QQmlComponent(qmlContext(this)->engine(),m_source,this);
    }
    else if(m_sourceComponent)
    {
        auto data = getROObjectData(m_sourceComponent);
        if(!data)
        {
            qDebug()<<"创建失败，组件未注册";
            return;
        }

        reason = {"comp",QString::number(data->id)};
        m_realComponent = m_sourceComponent;
    }

    QObject* current = nullptr;

    if(m_realComponent)
    {
        current = m_realComponent->create(m_realComponent->creationContext());
    }

    if(current)
    {
        current->setParent(this);
        registerObject(current,reason);
        setCurrent(current);
    }

}

QObject *ROLoader::handleCreation(const QStringList &reason)
{
    clean();

    m_block = false;
    QObject* ret = nullptr;
    if(reason[0] == "url")
    {
        setSource(reason[1]);
        setSourceComponent(nullptr);
        m_realComponent = new QQmlComponent(qmlContext(this)->engine(),m_source,this);
    }
    else if(reason[0] == "comp")
    {
        setSource(QUrl());

        auto comp = qobject_cast<QQmlComponent*>(getObjectById(reason[1].toInt()));
        setSourceComponent(comp);
        if(!comp)
        {
            qDebug()<<"找不到目标组件，创建对象失败";
        }
        m_realComponent = comp;
    }

    if(m_realComponent)
    {
        auto current = m_realComponent->create(m_realComponent->creationContext());
        current->setParent(this);

        setCurrent(current);
    }

    m_block = true;

    return ret;
}

void ROLoader::clean()
{
    if(!m_source.isEmpty())
    {
        if(m_realComponent)
        {
            delete m_realComponent;
            m_realComponent = nullptr;
        }
    }
    if(m_current)
    {
        delete m_current;
        m_current = nullptr;
    }
}

QObject *ROLoader::current() const
{
    return m_current;
}

void ROLoader::setCurrent(QObject *newCurrent)
{
    if (m_current == newCurrent)
        return;
    m_current = newCurrent;
    emit currentChanged();
}

void ROLoader::initialize()
{
    ROSyncCreation::initialize();
    if(role() == Host)//如果当前是host则依靠属性生成对象
    {
        validate();
        beginPropertyBindings();
        qDebug()<<"broadCast";
    }
    else if(role() == Client)//如果当前是Client则清除属性
    {
        m_block = false;
        setSource({});
        setSourceComponent({});
        m_block = true;
    }

}
